package com.platform.api;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Duang;
import com.jfinal.kit.Prop;
import com.jfinal.weixin.sdk.api.*;
import com.jfinal.wxaapp.api.WxaUserApi;
import com.platform.utils.EmojiUtils;
import com.qiniu.util.StringUtils;
import com.platform.annotation.IgnoreAuth;
import com.platform.entity.FullUserInfo;
import com.platform.entity.UserInfo;
import com.platform.entity.UserVo;
import com.platform.service.ApiUserService;
import com.platform.service.TokenService;
import com.platform.util.ApiBaseAction;
import com.platform.util.ApiUserUtils;
import com.platform.util.CommonUtil;
import com.platform.utils.CharUtil;
import com.platform.utils.R;
import com.platform.validator.Assert;
import org.apache.commons.collections.MapUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.platform.config.Constants.UserLevel1;
import static com.platform.util.CommonUtil.getProp;
import static com.platform.util.wechat.WechatUtil.setWxaConfig;

/**
 * API登录授权
 *
 * @author lipengjun
 * @email 939961241@qq.com
 * @date 2017-03-23 15:31
 */
@RestController
@RequestMapping("/api/auth")
public class ApiAuthController extends ApiBaseAction {
    private Logger logger = Logger.getLogger(getClass());
    @Autowired
    private ApiUserService userService;
    @Autowired
    private TokenService tokenService;

    static Prop prop = getProp();


    /**
     * 获取sessionKey
     *
     * @param code 登录时获取的 code
     * @return
     */
    @IgnoreAuth
    @RequestMapping("getSessionKey")
    public Object getSessionKey(@RequestParam String code) {
        setWxaConfig();
        WxaUserApi wxaUserApi = Duang.duang(WxaUserApi.class);
        ApiResult apiResult = wxaUserApi.getSessionKey(code);
        if (!apiResult.isSucceed()) {
            return toResponsFail(apiResult.getErrorMsg());
        }

        JSONObject data = JSONObject.parseObject(apiResult.getJson());
        Map<String, Object> result = new HashMap<>();
        result.put("session_key", data.getString("session_key"));
        result.put("openid", data.getString("openid"));

        return toResponsSuccess(result);
    }


    /**
     * 解密用户敏感数据
     *
     * @param sessionKey    会话密钥
     * @param encryptedData 明文
     * @param ivStr         加密算法的初始向量
     * @return
     */
    @IgnoreAuth
    @RequestMapping("getSensitiveInfo")
    public Object getSensitiveInfo(@RequestParam String sessionKey, @RequestParam String encryptedData, @RequestParam String ivStr) {
        setWxaConfig();
        WxaUserApi wxaUserApi = Duang.duang(WxaUserApi.class);
        ApiResult apiResult = wxaUserApi.getUserInfo(sessionKey, encryptedData, ivStr);
        if (!apiResult.isSucceed()) {
            return toResponsFail(apiResult.getErrorMsg());
        }
        return toResponsSuccess(apiResult.getJson());
    }


    /**
     * 微信公众号授权
     *
     * @param state    授权后跳转的URL
     * @param response 跳转
     * @throws IOException
     */
    @IgnoreAuth
    @RequestMapping("weixin_oauth")
    public void weixin_oauth(String state, HttpServletResponse response) throws IOException {
        String calbackUrl = prop.get("domain") + "/api/auth/oauth";
        String url = SnsAccessTokenApi.getAuthorizeURL(prop.get("appId"), calbackUrl, state, false);
        response.sendRedirect(url);
    }


    @IgnoreAuth
    @RequestMapping("oauth")
    public Object oauth(String code, String state, HttpServletResponse response) throws IOException {

        //用户同意授权，获取code
        if (code != null) {
            String appId = prop.get("appId");
            String secret = prop.get("appSecret");
            //通过code换取网页授权access_token
            SnsAccessToken snsAccessToken = SnsAccessTokenApi.getSnsAccessToken(appId, secret, code);
            String token = snsAccessToken.getAccessToken();
            String openId = snsAccessToken.getOpenid();
            //拉取用户信息(需scope为 snsapi_userinfo)
            ApiResult apiResult = SnsApi.getUserInfo(token, openId);

            if (apiResult.isSucceed()) {
                JSONObject jsonObject = JSON.parseObject(apiResult.getJson());
                String nickName = jsonObject.getString("nickname");
                int sex = jsonObject.getIntValue("sex");//用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
//                String city = jsonObject.getString("city");//城市
//                String province = jsonObject.getString("province");//省份
//                String country = jsonObject.getString("country");//国家
                String headimgurl = jsonObject.getString("headimgurl");

                Date nowTime = new Date();
                UserVo userVo = userService.queryByOpenId(openId);
                if (null == userVo) {
                    userVo = new UserVo();
                    userVo.setUsername("微信用户" + CharUtil.getRandomString(12));
                    userVo.setPassword(openId);
                    userVo.setRegister_time(nowTime);
                    userVo.setRegister_ip(this.getClientIp());
                    userVo.setLast_login_ip(userVo.getRegister_ip());
                    userVo.setLast_login_time(userVo.getRegister_time());
                    userVo.setWeixin_openid(openId);
                    userVo.setAvatar(headimgurl);
                    userVo.setGender(sex); // //性别 0：未知、1：男、2：女
                    userVo.setUser_level_id(UserLevel1);//默认为会员身份
                    userVo.setNickname(EmojiUtils.emojiConvert1(nickName));
                    userService.save(userVo);
                    //再次获取用户Id
                    userVo = userService.queryByOpenId(openId);
                } else {
                    userVo.setLast_login_ip(this.getClientIp());
                    userVo.setLast_login_time(nowTime);
                    userService.update(userVo);
                }

                Map<String, Object> tokenMap = tokenService.createToken(userVo.getUserId());
                String userToken = MapUtils.getString(tokenMap, "token");

                if (StringUtils.isNullOrEmpty(userToken)) {
                    return toResponsFail("登录失败");
                }
                //根据state 跳转到不同的页面
                if (Validator.isNotEmpty(state)) {
                    //会在后台加上token返回
                    if (state.contains("?")) {
                        String decode = URLUtil.decode(state + "&token=" + userToken);
                        response.sendRedirect(decode);
                    } else {
                        String decode = URLUtil.decode(state + "?token=" + userToken);
                        response.sendRedirect(decode);
                    }

                } else {
                    response.sendRedirect("http://pic.fs-cxqd.com/shopping/index.html");
                }
                return null;
            } else {
                return toResponsFail("登录失败");
            }

        } else {
            return toResponsFail("code is  null");
        }
    }

    /**
     * 登录
     */
    @IgnoreAuth
    @RequestMapping("login")
    public R login(String mobile, String password) {
        Assert.isBlank(mobile, "手机号不能为空");
        Assert.isBlank(password, "密码不能为空");

        //用户登录
        long userId = userService.login(mobile, password);

        //生成token
        Map<String, Object> map = tokenService.createToken(userId);

        return R.ok(map);
    }

    /**
     * 登录
     */
    @IgnoreAuth
    @RequestMapping("login_by_weixin")
    public Object loginByWeixin() throws UnsupportedEncodingException {
        JSONObject jsonParam = this.getJsonRequest();

        FullUserInfo fullUserInfo = null;
        String code = "";

        if (!StringUtils.isNullOrEmpty(jsonParam.getString("code"))) {
            code = jsonParam.getString("code");
        }

        if (null != jsonParam.get("userInfo")) {
            fullUserInfo = jsonParam.getObject("userInfo", FullUserInfo.class);
        }

        if (fullUserInfo == null) {
            return toResponsFail("userInfo为空");
        }

        Map<String, Object> resultObj = new HashMap<>();

        //
        UserInfo userInfo = fullUserInfo.getUserInfo();

        //获取openid
        String requestUrl = ApiUserUtils.getWebAccess(code);//通过自定义工具类组合出小程序需要的登录凭证 code
        logger.info("》》》组合token为：" + requestUrl);

        JSONObject sessionData = CommonUtil.httpsRequest(requestUrl, "GET", null);

        logger.info("sessionData为：" + sessionData);

        if (null == sessionData || StringUtils.isNullOrEmpty(sessionData.getString("openid"))) {
            return toResponsFail("登录失败");
        }

        //验证用户信息完整性
        String sha1 = CommonUtil.getSha1(fullUserInfo.getRawData() + sessionData.getString("session_key"));
        if (!fullUserInfo.getSignature().equals(sha1)) {
            return toResponsFail("登录失败");
        }


        Date nowTime = new Date();

        UserVo userVo = userService.queryByOpenId(sessionData.getString("openid"));
        if (null == userVo) {
            userVo = new UserVo();
            userVo.setUsername("微信用户" + CharUtil.getRandomString(12));
            userVo.setPassword(sessionData.getString("openid"));
            userVo.setRegister_time(nowTime);
            userVo.setRegister_ip(this.getClientIp());
            userVo.setLast_login_ip(userVo.getRegister_ip());
            userVo.setLast_login_time(userVo.getRegister_time());
            userVo.setWeixin_openid(sessionData.getString("openid"));
            userVo.setAvatar(userInfo.getAvatarUrl());
            userVo.setUser_level_id(UserLevel1);//默认为会员身份
            userVo.setGender(userInfo.getGender()); // //性别 0：未知、1：男、2：女
            userVo.setNickname(EmojiUtils.emojiConvert1(userInfo.getNickName()));
            userService.save(userVo);
        } else {//更新用户登录信息
            UserVo user = userService.queryObject(userVo.getUserId());
            user.setLast_login_ip(this.getClientIp());
            user.setLast_login_time(nowTime);
            userService.update(user);
        }
        userVo = userService.queryByOpenId(sessionData.getString("openid"));

        Map<String, Object> tokenMap = tokenService.createToken(userVo.getUserId());
        String token = MapUtils.getString(tokenMap, "token");

        if (null == userInfo || StringUtils.isNullOrEmpty(token)) {
            return toResponsFail("登录失败");
        }

        resultObj.put("token", token);
        resultObj.put("userInfo", userInfo);
        resultObj.put("userId", userVo.getUserId());

        return toResponsSuccess(resultObj);
    }

    /**
     * 小程序登录
     */
    @IgnoreAuth
    @RequestMapping("wxappLogin")
    public Object wxappLogin(@RequestParam String openid,
                             @RequestParam String avatarUrl,
                             @RequestParam Integer gender,
                             @RequestParam String nickName,
                             String mobile) throws UnsupportedEncodingException {

        Map<String, Object> resultObj = new HashMap<>();

        Date nowTime = new Date();

        UserVo userVo = userService.queryByOpenId(openid);
        if (null == userVo) {
            userVo = new UserVo();
            userVo.setUsername("微信用户" + CharUtil.getRandomString(12));
            userVo.setPassword(openid);
            userVo.setRegister_time(nowTime);
            userVo.setRegister_ip(this.getClientIp());
            userVo.setLast_login_ip(userVo.getRegister_ip());
            userVo.setLast_login_time(userVo.getRegister_time());
            userVo.setWeixin_openid(openid);
            userVo.setAvatar(avatarUrl);
            if(Validator.isNotEmpty(mobile)){
                userVo.setMobile(mobile);
            }
            userVo.setUser_level_id(UserLevel1);//默认为会员身份
            userVo.setGender(gender); // //性别 0：未知、1：男、2：女
            userVo.setNickname(EmojiUtils.emojiConvert1(nickName));
            userVo.setIntegral("0");
            userService.save(userVo);
        } else {//更新用户登录信息
            UserVo user = userService.queryObject(userVo.getUserId());
            if(Validator.isNotEmpty(mobile)){
                userVo.setMobile(mobile);
            }
            user.setLast_login_ip(this.getClientIp());
            user.setLast_login_time(nowTime);
            userService.update(user);
        }

        userVo = userService.queryByOpenId(openid);

        Map<String, Object> tokenMap = tokenService.createToken(userVo.getUserId());
        String token = MapUtils.getString(tokenMap, "token");

        if (StringUtils.isNullOrEmpty(token)) {
            return toResponsFail("登录失败");
        }

        resultObj.put("token", token);
        resultObj.put("userInfo", userVo);
        resultObj.put("userId", userVo.getUserId());

        return toResponsSuccess(resultObj);
    }


}
